package cn.dm.example.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

@Slf4j
public class SemaphoreExample4 {

    private final static int threadCount = 20;

    public static void main(String[] args) throws Exception {

        ExecutorService exec = Executors.newCachedThreadPool();

        final Semaphore semaphore = new Semaphore(3);

        for (int i = 0; i < threadCount; i++) {
            final int threadNum = i;
            exec.execute(() -> {
                try {
                    if (semaphore.tryAcquire(5000, TimeUnit.MILLISECONDS)) { // 尝试获取一个许可
                        test(threadNum);
                        semaphore.release(); // 释放一个许可
                    }
                } catch (Exception e) {
                    log.error("exception", e);
                }
            });
        }
        exec.shutdown();
        /*
         * 结果
         * 16:15:03.732 [pool-1-thread-3] INFO cn.dm.example.aqs.SemaphoreExample4 - 2
         * 16:15:03.732 [pool-1-thread-1] INFO cn.dm.example.aqs.SemaphoreExample4 - 0
         * 16:15:03.732 [pool-1-thread-2] INFO cn.dm.example.aqs.SemaphoreExample4 - 1
         * 16:15:04.748 [pool-1-thread-5] INFO cn.dm.example.aqs.SemaphoreExample4 - 4
         * 16:15:04.748 [pool-1-thread-6] INFO cn.dm.example.aqs.SemaphoreExample4 - 5
         * 16:15:04.748 [pool-1-thread-7] INFO cn.dm.example.aqs.SemaphoreExample4 - 6
         * 16:15:05.760 [pool-1-thread-8] INFO cn.dm.example.aqs.SemaphoreExample4 - 7
         * 16:15:05.760 [pool-1-thread-9] INFO cn.dm.example.aqs.SemaphoreExample4 - 8
         * 16:15:05.760 [pool-1-thread-4] INFO cn.dm.example.aqs.SemaphoreExample4 - 3
         * 16:15:06.769 [pool-1-thread-11] INFO cn.dm.example.aqs.SemaphoreExample4 - 10
         * 16:15:06.768 [pool-1-thread-10] INFO cn.dm.example.aqs.SemaphoreExample4 - 9
         * 16:15:06.770 [pool-1-thread-13] INFO cn.dm.example.aqs.SemaphoreExample4 - 12
         * 16:15:07.774 [pool-1-thread-12] INFO cn.dm.example.aqs.SemaphoreExample4 - 11
         * 16:15:07.775 [pool-1-thread-14] INFO cn.dm.example.aqs.SemaphoreExample4 - 13
         * 16:15:07.777 [pool-1-thread-16] INFO cn.dm.example.aqs.SemaphoreExample4 - 15
         */
    }

    private static void test(int threadNum) throws Exception {
        log.info("{}", threadNum);
        Thread.sleep(1000);
    }
}
